package cn.xetsoft.supermarket.service.impl;

import cn.xetsoft.supermarket.common.DataResponse;
import cn.xetsoft.supermarket.common.Role;
import cn.xetsoft.supermarket.dao.DbDao;
import cn.xetsoft.supermarket.entity.*;
import cn.xetsoft.supermarket.service.*;
import cn.xetsoft.supermarket.util.DbConfig;
import cn.xetsoft.supermarket.util.FileUtil;
import cn.xetsoft.supermarket.util.JDBCUtils;
import cn.xetsoft.supermarket.util.PropertiesUtil;
import cn.xetsoft.supermarket.view.StartFrame;
import cn.xetsoft.supermarket.vo.OrderVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;

import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

/**
 * @author 侯国强
 * @version 1.0
 * @Description 设置服务服务
 * @since 2020/12/21 21:08
 */

@Slf4j //使用lombok日志的注解
public class SettingServiceImpl implements SettingService {
    private DbDao dbDao;
    //execl 数据库服务对象创建
    private ExcelService excelService = Bean.getExcelServiceInstance();
    //商品数据库服务创建 通过单例创建
    private GoodService goodService = Bean.getGoodServiceInstance();
    //订单数据库服务创建 通过单例创建
    private OrderService orderService = Bean.getOrderServiceInstance();
    //订单商品数据库服务创建 通过单例创建
    private OrderItemService orderItemService = Bean.getOrderItemServiceInstance();
    //用户数据库服务创建 通过单例创建
    private UserService userService = Bean.getUserServiceInstance();

    public SettingServiceImpl(DbDao dbDao) {
        this.dbDao = dbDao;
    }
    


    /**
     * 初始化系统
     *  4041 初始化检测数据库不存在
     *  4042 初始化检测数据表不存在
     *  建议调用数据库设置页面初始化页面
     *  500 异常
     */
    @Override
    public DataResponse initSystem() {

        try {
            //检查是否存在数据库连接
            Connection connection = JDBCUtils.getInstanceConnection();
            if (null == connection){
                //日志警告提示
                log.warn("连接失败");
                return JDBCUtils.getResponse();
            }
            //通知进度
            StartFrame.TaskSuccess(20); //代表通知窗口当前任务完成,进度条增加30
            /**
             * 检查数据库是否存在
             */
            String dbName = JDBCUtils.getDbConfig().getDatabase();
            boolean b = dbDao.existDatabase(dbName);
            if (!b){
                //日志警告提示
                log.warn("数据库不存在");
                return DataResponse.error(4041,"数据库不存在");
            }

            //选中数据库
            dbDao.useDatabase(dbName);

            //通知进度
            StartFrame.TaskSuccess(20); //代表通知窗口当前任务完成,进度条增加30

            /**
             * 检测数据表是否存在
             */
            StringBuilder info = new StringBuilder();
            //判断用户数据表是否存在
            boolean user = dbDao.existTable(dbName,"user");
            if (!user){
                info.append("用户");
            }

            //通知进度
            StartFrame.TaskSuccess(20); //代表通知窗口当前任务完成,进度条增加30

            //判断数商品据表是否存在
            boolean good = dbDao.existTable(dbName,"good");
            if (!good){
                info.append(",").append("商品");
            }

            //通知进度
            StartFrame.TaskSuccess(20); //代表通知窗口当前任务完成,进度条增加30

            //判断订单数据表是否存在
            boolean order = dbDao.existTable(dbName,"order");
            if (!order){
                info.append(",").append("订单");
            }

            //通知进度
            StartFrame.TaskSuccess(20); //代表通知窗口当前任务完成,进度条增加30

            //判断订单商品数据表是否存在
            boolean orderItem = dbDao.existTable(dbName,"order_item");
            if (!orderItem){
                info.append(",").append("订单商品");
            }
            info.append("数据表不存在");

            //通知进度
            StartFrame.TaskSuccess(20); //代表通知窗口当前任务完成,进度条增加30

            //判断是否所有表都不存在
            if (!user || !good || !order || !orderItem){
                //日志警告提示
                log.warn("数据表不存在: {}",info);
                return DataResponse.error(4042,info.toString());
            }


        } catch (SQLException throwables) {
            //日志警告提示
            log.warn("异常 -> {}",throwables.getMessage());
            return DataResponse.error(500,throwables.getMessage());
        }
        return DataResponse.success("检测连接成功！");
    }

    /**
     * 初始化数据库
     * @param isClear 是否清库
     */
    @Override
    public DataResponse initDatabase( boolean isClear) {

        try {
            String dbName = JDBCUtils.getDbConfig().getDatabase();
            //判断是否存在数据库
            if (dbDao.existDatabase(dbName) && isClear){//存在删除
                dbDao.deleteDatabase(JDBCUtils.getDbConfig().getDatabase());
            }
            //数据库不存在，创建数据库
            if (!dbDao.existDatabase(JDBCUtils.getDbConfig().getDatabase())){
                //创建数据库
                dbDao.createDatabase(JDBCUtils.getDbConfig().getDatabase());
            }

            //使用数据库
            dbDao.useDatabase(JDBCUtils.getDbConfig().getDatabase());
            /**
             * 创建数据表
             */
            //商品数据表不存在创建数据表
            if (!dbDao.existTable(dbName,"good")) {
                dbDao.createTable(PropertiesUtil.getProperty("db.table.good"));
            }
            //订单数据表不存在创建数据表
            if (!dbDao.existTable(dbName,"order")) {
                dbDao.createTable(PropertiesUtil.getProperty("db.table.order"));
            }
            //订单商品数据表不存在创建数据表
            if (!dbDao.existTable(dbName,"order_item")) {
                dbDao.createTable(PropertiesUtil.getProperty("db.table.orderItem"));
            }
            //用户数据表不存在创建数据表
            if (!dbDao.existTable(dbName,"user")) {
                dbDao.createTable(PropertiesUtil.getProperty("db.table.user"));
            }
            userService.register(new User("root","root","超级管理员","18800000000","未排班",Role.ROLE_ROOT));
        } catch (SQLException throwables) {
            //日志警告提示
            log.warn("异常 -> {}",throwables.getMessage());
            return DataResponse.error(throwables.getMessage());
        }
        return DataResponse.success("初始化完成");
    }

    @Override
    public DataResponse initDbConfig(DbConfig dbConfig) {
        /**
         * 如果穿空使用系统默认
         */
        if (null != dbConfig){
            log.debug("数据库配置信息： {}",dbConfig);
            JDBCUtils.init(dbConfig);
            /**
             * 更新配置
             */
            PropertiesUtil.update("db.username",dbConfig.getUsername());
            PropertiesUtil.update("db.password",dbConfig.getPassword());
            PropertiesUtil.update("db.dbname",dbConfig.getDatabase());
            PropertiesUtil.update("db.host",dbConfig.getAddress());
            PropertiesUtil.update("db.port",String.valueOf(dbConfig.getPort()));
            JDBCUtils.close();
            return DataResponse.success("保存成功");
        }
        return DataResponse.error("保存错误");
    }

    @Override
    public DataResponse initGoodData(String filename) {

        if (!FileUtil.isFile(filename)){
            //日志警告提示
            log.warn("文件不存在");
            return DataResponse.error("文件不存在");
        }
        /**
         * 从表格读取商品数据
         */
        List<Good> goods = excelService.readGoodExcel(filename);
        if (goods == null || goods.size() == 0){
            //日志警告提示
            log.warn("数据为空或者商品信息工作表不存在");
            return DataResponse.error("数据为空或者商品信息工作表不存在");
        }
        /**
         * 加入数据库
         */
        for (Good good : goods) {
            goodService.insert(good);
        }
        return DataResponse.success("操作完成");
    }

    @Override
    public DataResponse initOrderData(String filename ) {
        /**
         * 从配置文件从获取
         */
        if (!FileUtil.isFile(filename)){
            //日志警告提示
            log.warn("文件不存在");
            return DataResponse.error("文件不存在");
        }
        System.out.println(filename);
        /**
         * 从表格读取订单数据
         */
        List<Order> orders = excelService.readOrderExcel(filename);
        if (orders == null || orders.size() == 0){
            //日志警告提示
            log.warn("数据为空或者商品信息工作表不存在");
            return DataResponse.error("数据为空或者订单信息工作表不存在");
        }
        /**
         * 加入数据库
         */
        for (Order order : orders) {
            orderService.insert(order);
        }
        return DataResponse.success("操作完成");
    }

    @Override
    public DataResponse initOrderItemData(String filename) {
        //判断文件是否存在
        if (!FileUtil.isFile(filename)){
            //日志警告提示
            log.warn("文件不存在");
            return DataResponse.error("文件不存在");
        }
        /**
         * 从表格读取订单商品数据
         */
        List<OrderItem> orderItems = excelService.readOrderItemExcel(filename);
        if (orderItems == null || orderItems.size() == 0){
            //日志警告提示
            log.warn("数据为空或者订单商品信息工作表不存在");
            return DataResponse.error("数据为空或者订单商品信息工作表不存在");
        }
        /**
         * 加入数据库
         */
        for (OrderItem orderItem : orderItems) {
            orderItemService.insert(orderItem);
        }
        return DataResponse.success("操作完成");
    }

    @Override
    public DataResponse initUserData(String filename) {
        //判断文件是否存在
        if (!FileUtil.isFile(filename)){
            //日志警告提示
            log.warn("文件不存在");
            return DataResponse.error("文件不存在");
        }
        /**
         * 从表格读取用户数据
         */
        List<User> users = excelService.readUserExcel(filename);
        if (users == null || users.size() == 0){
            //日志警告提示
            log.warn("数据为空或者订单信息工作表不存在");
            return DataResponse.error("数据为空或者订单信息工作表不存在");
        }
        /**
         * 加入数据库
         */
        for (User user : users) {
            //password MD5
            String password = PropertiesUtil.getProperty("excel.export.user.password");
            if (password == null){
                password = "123456";
            }
            //设置初始化密码123456
            user.setPassword(password);
            //通过用户服务注册
            userService.register(user);
        }

        return DataResponse.success("操作完成");
    }

    /**
     * 导出数据库数据
     *  @param filename 导出文件名
     * @param role 角色 非管理员不能导出用户
     * @param exportSelect
     */
    @Override
    public DataResponse exportDbData(String filename, Role role, ExportSelect exportSelect) {

        if (null == exportSelect || (!exportSelect.isGood() && !exportSelect.isOrder() && !exportSelect.isUser())){
            //日志警告提示
            log.warn("没有导出表");
            return DataResponse.error("没有导出表");
        }
        /**
         * 定义可能导出对象
         * 如果不导出穿空
         */
        List<Good> goods = null;
        List<Order> orders = null;
        List<OrderItem> orderItems= null;
        List<User> users = null;

        if (exportSelect.isGood()) {
            DataResponse<List<Good>> goodDataResponse = goodService.queryAll();
            if (goodDataResponse.isSuccess()){
                goods = goodDataResponse.getData();
            } else {
                return goodDataResponse;
            }
        }
        /**
         * 订单包括订单和订单商品
         */
        if (exportSelect.isOrder()) {
            DataResponse<OrderVo> orderVoDataResponse = orderService.queryAll();
            if (orderVoDataResponse.isSuccess()){
                orders = orderVoDataResponse.getData().getOrders();
            } else {
                return orderVoDataResponse;
            }
            DataResponse<List<OrderItem>> orderItemDataResponse = orderItemService.queryAll();
            if (orderItemDataResponse.isSuccess()){
                orderItems = orderItemDataResponse.getData();
            } else {
                return orderItemDataResponse;
            }
        }
        /**
         * 需要导出 并且 管理员以上才能导出用户数据
         */
        if (exportSelect.isUser() && role.getCode() >= 2){
            DataResponse<List<User>> userDataResponse = userService.queryAll();
            if (userDataResponse.isSuccess()){
                users = userDataResponse.getData();
            } else {
                return userDataResponse;
            }
        }

        DataResponse response = excelService.writeAllExcel(goods, orders, orderItems, users, filename);
        try {
            Runtime.getRuntime().exec("cmd /c start " + filename);
        } catch (IOException e) {
            //日志警告提示
            log.warn("异常 -> {}",e.getMessage());
        }
        return response;
    }

    @Override
    public DataResponse createDataTemplate(String filename) {
        DataResponse response = excelService.writeTemplateExcel(filename);

        try {
            Runtime.getRuntime().exec("cmd /c start " + filename);
        } catch (IOException e) {
            //日志警告提示
            log.warn("异常 -> {}",e.getMessage());
        }

        return response;
    }

    /**
     * 查看日志最后几行
     *
     * @param row
     */
    @Override
    public DataResponse tailLogInfo(int row) {

        File file = new File("logs");
        File[] files = file.listFiles();
        String filename = files[files.length-1].toString();
        try {
            String s = FileUtil.readLastRows(filename,null,100);
            return DataResponse.success(s);
        } catch (IOException e) {
            log.warn(e.getMessage());
            return DataResponse.error(e.getMessage());
        }
    }
}
